Use the otplib library to generate TOTP secrets and verify codes. On enable, store the secret after verifying the first code. Modify the login flow to issue a limited pre-2FA token when 2FA is enabled — the client must then POST the TOTP code to exchange it for full access tokens.
Never enable 2FA without verifying the first code — confirm the user has set up the authenticator app correctly.
The temp token has a short expiry (5 minutes) and a distinct claim — prevents it from being used as a full access token.
Store the TOTP secret encrypted at rest — use AES-256 via a KMS or field-level encryption.
Allow backup codes at registration — 6-10 single-use codes for account recovery without the authenticator.
Rate-limit the 2FA verification endpoint — TOTP codes have limited combinations (6 digits).